home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 15084 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.5 KB  |  114 lines

  1. Path: keats.ugrad.cs.ubc.ca!not-for-mail
  2. From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
  3. Newsgroups: comp.lang.c,comp.unix.programmer
  4. Subject: Re: Q: '\n' character
  5. Date: 16 Apr 1996 16:33:56 -0700
  6. Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
  7. Message-ID: <4l1ap4INNhsc@keats.ugrad.cs.ubc.ca>
  8. References: <4kj66f$k0o@ren.cei.net> <4ku8f9$d3o@mark.ucdavis.edu> <4kumbqINNgcr@mayne.ugrad.cs.ubc.ca> <4l13uu$mva@mark.ucdavis.edu>
  9. NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
  10.  
  11. In article <4l13uu$mva@mark.ucdavis.edu>,
  12. James Knight <knight@quad.cs.ucdavis.edu> wrote:
  13. >Yes, but which one is faster.  I did this experiment for a class I was teaching,
  14. >where I compared all combinations of fgetc, fgets, fputc and fputs for a cat
  15. >program that does line by line reading. The fgetc/fputc combination ran in 
  16. >about 10 seconds (I think I was reading 1MB of text), the fgets/fputc and
  17. >fgetc/fputs combinations ran in about 6.5-7 seconds and the fgets/fputs
  18. >combination ran in 3.5 seconds.  I can post more details about this, if you
  19. >like.
  20.  
  21. Please do! Mind you, a cat program is somewhat trivial. In implementing cat with
  22. fgets()/fputs(), you don't have to care whether there is a newline at the end!
  23. fgets()/fputs() seem almost ideally matched to a cat-like program, though
  24. fread() and fwrite() are likely to do even better since they don't have to look
  25. for a newline at all.
  26.  
  27. But once you start having to scan the buffer with strlen(), strchr() and
  28. friends, the advantage of using fgets() may diminish.
  29.  
  30. Also, you used fputc() and fgetc(). These are not likely to be as fast as the
  31. getc() and putc() macro equivalents which access the FILE structure's buffer
  32. directly. (Do you know the implementation details of these functions/macros on
  33. the system that served as your testbench?)
  34.  
  35. On this system, when I write
  36.  
  37.         while((c = getc(in)) != EOF) putc(out,c);
  38.  
  39. I get something like this, after the pre-processing stage and a little cosmetic
  40. cleanup 
  41.  
  42.  
  43. while ((c = ((in)->_IO_read_ptr >= (in)->_IO_read_end
  44.     ? __uflow(in)
  45.     : *(unsigned char *) (in)->_IO_read_ptr++))        != (-1))
  46.  
  47.     (((c)->_IO_write_ptr >= (c)->_IO_write_end)
  48.         ? __overflow(c, (unsigned char) (out))
  49.         : (unsigned char) (*(c)->_IO_write_ptr++ = (out)));
  50.  
  51. It looks a little messy, but it's the whole logic for copying from one buffered
  52. IO stream to another, minus the definitions for the __uflow and __overflow glue
  53. functions. Let's see what optimized x86 code looks like for the construct:
  54.  
  55.  
  56.     .file    "test2.c"
  57. gcc2_compiled.:
  58. ___gnu_compiled_c:
  59. .text
  60.     .align 4
  61. .globl _foo
  62. _foo:
  63.     pushl %esi
  64.     pushl %ebx
  65.     movl 12(%esp),%esi
  66.     movl 16(%esp),%ebx
  67.     .align 2,0x90
  68. L10:
  69.     movl 4(%esi),%eax
  70.     cmpl %eax,8(%esi)
  71.     ja L13
  72.     pushl %esi
  73.     call ___uflow
  74.     addl $4,%esp
  75.     jmp L14
  76.     .align 4,0x90
  77. L13:
  78.     movzbl (%eax),%eax
  79.     incl 4(%esi)
  80. L14:
  81.     cmpl $-1,%eax
  82.     je L11
  83.     movl 20(%ebx),%edx
  84.     cmpl %edx,24(%ebx)
  85.     ja L15
  86.     andl $255,%eax
  87.     pushl %eax
  88.     pushl %ebx
  89.     call ___overflow
  90.     addl $8,%esp
  91.     jmp L10
  92.     .align 4,0x90
  93. L15:
  94.     movb %al,(%edx)
  95.     incl 20(%ebx)
  96.     jmp L10
  97.     .align 4,0x90
  98. L11:
  99.     popl %ebx
  100.     popl %esi
  101.     ret
  102.  
  103. That's not bad for what it does. (I put a simple function wrapper around the
  104. loop, declared the in, out and c variables, and compiled with -O6
  105. -fomit-frame-pointer).
  106.  
  107. I suspect that if your cat program had been rewritten to do a dumb getc()
  108. putc() loop until EOF, it would have beat the fgets(), just by virtue of not
  109. having to 1) make a function call, 2) look for newlines and 3) copy the data
  110. into a redundant bounce buffer that acts as a middleman between two FILE stream
  111. buffers.
  112. -- 
  113. I'm not really a jerk, but I play one on Usenet.
  114.